﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TechTalk.SpecFlow;
using Sai.Core;
using Xunit;

namespace Sai.Specs.Steps
{
	[Binding]
	public class FolderComparisonSteps
	{
		const string projectKey = "project";
		const string commonFilesKey = "commonFiles";
		int baseFileCount = 10;

		[Given(@"A version of a library")]
		public void GivenAVersionOfALibrary()
		{
			ProductReleaseProject project = new ProductReleaseProject();
			
			// we start off completely equal
			project.FromVersion = "Old";
			project.ToVersion = "New";

			List<string> commonFiles = CreateAssemblies(baseFileCount);

			project.AddFromFiles(commonFiles);

			ScenarioContext.Current.Set <List<string>>(commonFiles, commonFilesKey);
			ScenarioContext.Current.Set<ProductReleaseProject>(project, projectKey);
		}

		[When(@"(.*) assemblies are added in the next version")]
		public void WhenNAssembliesAreAddedInTheNextVersion(int added)
		{
			ProductReleaseProject project = ScenarioContext.Current.Get<ProductReleaseProject>(projectKey);

			var commonFiles = ScenarioContext.Current.Get<List<string>>(commonFilesKey);

			project.AddToFiles(commonFiles);
			project.AddToFiles(CreateAssemblies(added));

			ScenarioContext.Current.Set<ProductReleaseProject>(project, projectKey);
		}

		[When(@"(.*) assemblies are removed in the next version")]
		public void WhenNAssembliesAreRemovedInTheNextVersion(int removed)
		{
			ProductReleaseProject project = ScenarioContext.Current.Get<ProductReleaseProject>(projectKey);

			var commonFiles = ScenarioContext.Current.Get<List<string>>(commonFilesKey);

			commonFiles.RemoveRange(0, removed);

			project.AddToFiles(commonFiles);

			ScenarioContext.Current.Set<ProductReleaseProject>(project, projectKey);
		}

		[When(@"(.*) assemblies are added and (.*) assemblies are removed in the next version")]
		public void WhenNAssembliesAreRemovedInTheNextVersion(int added, int removed)
		{
			ProductReleaseProject project = ScenarioContext.Current.Get<ProductReleaseProject>(projectKey);

			var commonFiles = ScenarioContext.Current.Get<List<string>>(commonFilesKey);

			commonFiles.RemoveRange(0, removed);

			project.AddToFiles(commonFiles);
			project.AddToFiles(CreateAssemblies(added));

			ScenarioContext.Current.Set<ProductReleaseProject>(project, projectKey);
		}

		[Then(@"the result should show (.*) assemblies have been added")]
		public void ThenTheResultShouldShowNAssembliesHaveBeenAdded(int addedAssemblyCount)
		{
			ProductReleaseProject project = ScenarioContext.Current.Get<ProductReleaseProject>(projectKey);

			AssemblyComparisonBuilder builder = new AssemblyComparisonBuilder(project, FileSystemValidationOption.Off);

			var comparisonCollection = builder.Build();

			int added = comparisonCollection.Count(x => x.Result == AssemblyComparisonResult.Added);

			Assert.Equal(addedAssemblyCount, added);
		}

		[Then(@"the result should show (.*) assemblies have been removed")]
		public void ThenTheResultShouldShowNAssembliesHaveBeenRemoved(int removedAssemblyCount)
		{
			ProductReleaseProject project = ScenarioContext.Current.Get<ProductReleaseProject>(projectKey);

			AssemblyComparisonBuilder builder = new AssemblyComparisonBuilder(project, FileSystemValidationOption.Off);

			var comparisonCollection = builder.Build();

			int removed = comparisonCollection.Count(x => x.Result == AssemblyComparisonResult.Removed);

			Assert.Equal(removedAssemblyCount, removed);
		}

		private List<string> CreateAssemblies(int count)
		{
			List<string> files = new List<string>();

			for (int i = 0; i < count; ++i)
			{
				files.Add(string.Format("Assembly_{0}", Guid.NewGuid().ToString()));
			}

			return files;
		}
	}
}
